﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Security.Permissions;

using Model.Crafters;
using Model.Adventure;

namespace Model.Items
{

    [Serializable]
    public abstract class Item : INotifyPropertyChanged, ISerializable
    {

        protected String _BaseName;
        protected String _Name;
        protected int _XPAwarded; //xp awarded for completing item
        protected Crafter _Crafter; //crafter crafting the item
        protected int _ManHours; //man hours required to complete item
        protected double _ManHoursDone; //man hours done on the item
        protected double _Price;   

        //usage stats
        protected bool _Two_Hander;
        protected double _Attack_Rating, _Defense_Rating;
        protected Damage _damage_stats;

        public virtual String Name { get; set; }
        public virtual int Aesthetic { get; set; }
        public virtual double MinPrice { get; set; }
        public virtual int Quality { get; set; }
        
        public Item() { } //empty ctor for serialization

        protected Item(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new System.ArgumentNullException("info");
            //Console.WriteLine("Serialization ctor in Item");
            //public vars
            Price = (double)info.GetValue("Price", typeof(double));
            BaseName = (string)info.GetValue("BaseName", typeof(string));
            XPAwarded = (int)info.GetValue("XPAwarded", typeof(int));
            //crafter = info.GetValue("crafter", typeof(Crafter)) as Crafter;
            ManHours = (int)info.GetValue("ManHours", typeof(int));
            ManHoursDone = (double)info.GetValue("ManHoursDone", typeof(double));
            //virtual vars
            Name = (string)info.GetValue("Name", typeof(string));
            Aesthetic = (int)info.GetValue("Aesthetic", typeof(int));
            MinPrice = (double)info.GetValue("MinPrice", typeof(double));
            Quality = (int)info.GetValue("Quality", typeof(int));

        }

        //stats regarding the use of the item by a hero/NPC
        public bool TwoHander
        {
            get { return _Two_Hander; }
            set
            {
                _Two_Hander = value;
                NotifyPropertyChanged("TwoHander");
            }
        }

        public double Attack_Rating
        {
            get { return _Attack_Rating; }
            set
            {
                _Attack_Rating = value;
                NotifyPropertyChanged("Attack_Rating");
            }
        }

        public double Defense_Rating
        {
            get { return _Defense_Rating; }
            set
            {
                _Defense_Rating = value;
                NotifyPropertyChanged("Defense_Rating");
            }
        }

        public Damage Damage_Stats
        {
            get { return _damage_stats; }
            set
            {
                _damage_stats = value;
            }
        }

        public double Price
        {
            get { return _Price; }
            set
            {
                _Price = value;
                NotifyPropertyChanged("Price");                
            }
        }

        public String BaseName //the basic name "inherited" by anything that is crafted from it
        {
            get { return _BaseName; }
            set
            {
                _BaseName = value;
                NotifyPropertyChanged("BaseName");
                NotifyPropertyChanged("Name");
            }
        }        

        public int XPAwarded
        {
            get { return _XPAwarded; }
            set
            {
                _XPAwarded = value;
                NotifyPropertyChanged("XPAwarded");
            }
        }

        public Crafter crafter
        {
            get { return _Crafter; }
            set
            {
                _Crafter = value;
                NotifyPropertyChanged("crafter");
            }
        }

        public int ManHours
        {
            get { return _ManHours; }
            set
            {
                _ManHours = value;
                NotifyPropertyChanged("ManHours");
            }
        }

        public double ManHoursDone
        {
            get { return _ManHoursDone; }
            set
            {
                _ManHoursDone = value;
                NotifyPropertyChanged("ManHoursDone");
                NotifyPropertyChanged("Progress");
            }
        }

        public double Progress
        {
            get { double p = 100 * (_ManHoursDone / _ManHours); return (p > 100 ? 100 : p); }
        }  

        protected double ComputeQuality(double source, double skill)
        {
            return source * skill / 100;
        }

        protected double ComputeAesthetic(double source, double skill)
        {
            return source * skill / 100;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        [SecurityPermission(SecurityAction.LinkDemand,
        Flags = SecurityPermissionFlag.SerializationFormatter)]
        public virtual void GetObjectData(
        SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new System.ArgumentNullException("info");
            //Console.WriteLine("GetObjectData in Item");
            info.AddValue("Name", Name);
            info.AddValue("Price", Price);
            info.AddValue("BaseName", BaseName);
            info.AddValue("XPAwarded", XPAwarded);
            //info.AddValue("crafter", crafter);
            info.AddValue("ManHours", ManHours);
            info.AddValue("ManHoursDone", ManHoursDone);
            info.AddValue("MinPrice", MinPrice);
            info.AddValue("Aesthetic", Aesthetic);
            info.AddValue("Quality", Quality);
        }
    }
}
